package io.github.annyylxyms.gyn.gateway.demo;

import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono;

/**
 * hello handler
 * 分离逻辑和聚合点
 * @author annyylxyms
 * @create 2024.12.8
 */
@Component
public class HelloHandler {
    /**
     * GatewayRouter返回的路由函数，调用handle方法
     * @param request
     * @return
     */
    Mono<ServerResponse> handle(ServerRequest request) {
        //模拟调用rpc(要提前启动自己做的rpc、配置中心及注册中心)
        String url = "http://localhost:8081/gynrpc";
        String requestJson = """
                {
                    "service":"cn.gyn.gynrpc.demo.api.UserService",
                    "methodSign":"findById@1_int",
                    "args":[100]
                }
                """;
        //使用WebClient发送HTTP请求:httpclient、OKhttp有啥用啥，都没有用jdk自带的urlcommit，会自己封装
        //.retrieve()用于拿到响应
        WebClient client = WebClient.create(url);
        Mono<ResponseEntity<String>> entity = client.post().header("Content-Type", "application/json")
                .bodyValue(requestJson).retrieve().toEntity(String.class);

        //return ServerResponse.ok().body(Mono.just("hello,gateway."), String.class);
        //上行另一种写法：bodyValue方法，直接返回响应体，不用再封装
        //return ServerResponse.ok().bodyValue("hello,gateway.");
        Mono<String> body = entity.map(ResponseEntity::getBody);
        body.subscribe(source -> System.out.println("response:" + source));
        //return ServerResponse.ok().body(body, String.class);//返回文本格式的响应:{"status":true,"data":{"id":100,"name":"KK-V1-8081_1716296548693"},"ex":nuLL}
        return ServerResponse.ok()
                .header("Content-Type", "application/json")
                .header("gyn.gw.version","v1.0.0")
                .body(body, String.class);//返回json格式的响应，见flomo笔记：https://v.flomoapp.com/mine/?memo_id=MTUwNjA3ODQy
        //mono继承了core publisher，所以可以用mono的subscribe方法来订阅，但是一般不用，因为是异步的
        //mono 和 flux 都是publisher，都是数据提供者，可以订阅，但是mono只能订阅一次，而flux可以订阅多次
    }
}
